

import { LocalDataType, TableInfo } from "./DBDefine";
import { TableParser } from "./TableParser";
import { LocalData } from "./LocalData";
import { Sqlite3Mgr } from "./Sqlite3Mgr";
import { engine } from "../../engine/engine";
export class LocalTable {


    protected cfg: TableInfo = null;

    protected _tableParser: TableParser

    protected localData: LocalData<any> = new LocalData()

    private _existFlag: boolean = false;

    setCfg(cfg: TableInfo) {
        this.cfg = cfg;
        if (this.cfg.dbName) {
            this.dbName = this.cfg.dbName
        }
        this._tableParser = new TableParser(cfg.type)
        this.localData.primaryKeyName = this._tableParser.primaryKeyName;
    }

    protected _tbName: string;

    protected _dbName: string

    get dbName() {
        return this._dbName;
    }



    set dbName(name: string) {
        this._dbName = name;
    }

    set tbName(n: string) {
        this._tbName = n;
    }

    get tbName() {
        return this._tbName;
    }

    get existFlag() {
        return this._existFlag;
    }

    set existFlag(flag: boolean) {
        this._existFlag = flag;
    }

    //init 初始化的数据最好是及时存储，然后调用data的init。
    protected init(): Promise<any> {
        return new Promise((reslove: Function, reject: Function) => {
            reslove()
        })
    }

    delete() {
        var sqlStr = 'DROP TABLE ' + this.tbName
        return new Promise((reslove: Function, reject: Function) => {
            this.isExist().then((flag: boolean) => {
                if (flag) {
                    Sqlite3Mgr.execData(this.dbName, sqlStr).then((err: string) => {
                        if (!err) {
                            this.existFlag = false;
                        }
                        reslove(err)
                    })
                } else {
                    reslove('')
                }
            })

        })
    }

    isExist() {
        return new Promise((reslove: Function, reject: Function) => {
            this.getTableInfo().then((list: any[]) => {
                // Debug.warn(' list && list.length > 0', list)
                reslove(list && list.length > 0)
            })
        })
    }

    getTableInfo() {
        let sqlStr = "SELECT * FROM sqlite_master where type ='table' and name ='" + this.tbName + "'"
        return Sqlite3Mgr.allData(this._dbName, sqlStr)
    }

    getData(sqlStr: string, ...data: any): Promise<any> {
        return Sqlite3Mgr.getData(this._dbName, sqlStr, ...data)
    }

    setData(sqlStr: string, ...data: any): Promise<any> {
        return Sqlite3Mgr.setData(this._dbName, sqlStr, ...data)
    }

    private execData(sqlStr: string): Promise<any> {
        return Sqlite3Mgr.execData(this._dbName, sqlStr)
    }

    allData(sqlStr: string, ...data: any): Promise<any> {
        return Sqlite3Mgr.allData(this._dbName, sqlStr, ...data)
    }

    create(): Promise<any> {
        var sqlStr = 'CREATE TABLE ' + this.tbName + ' ' + this._tableParser.typeStr;
        return new Promise((reslove: Function, reject: Function) => {
            Sqlite3Mgr.execData(this.dbName, sqlStr).then((err: string) => {
                if (!err) {
                    this.existFlag = true;
                }
                reslove(err)
            })
        })
        // return
    }

    setObj(obj: any, key: string) {
        let data = this.getAllList();
        if (data) {
            obj[key] = data;
        } else {
            engine.warn(' data is null ', this.localData)
        }
    }

    getAllList(filter: any = null) {
        return this.localData.getAllList(filter);
    }



    load() {
        return new Promise((reslove: Function, reject: Function) => {
            this.isExist().then((flag: boolean) => {
                // LogUtils.log(' flag ', flag, this.tbName, this.dbName)
                this.existFlag = flag;
                if (!flag) {
                    if (!this.cfg.notAudoCreate) {
                        this.create().then((error: string) => {
                            if (!error) {
                                this.existFlag = true;
                                this.init().then(() => {
                                    reslove()
                                });
                            } else {
                                reslove(error)
                            }
                        })
                    } else {
                        reslove()
                    }

                } else {
                    this.read().then(() => {
                        reslove()
                    })

                }
            })
        })
    }

    getAll() {
        return new Promise((reslove: Function, reject: Function) => {
            var sqlStr = 'select *  from ' + this.tbName;
            this.allData(sqlStr).then((row: any[]) => {
                let temp = this._tableParser.exchangeListToJS(row)
                reslove(temp)
            })
        })
    }

    read() {
        // LogUtils.log(' read ')
        return new Promise((reslove: Function, reject: Function) => {
            this.getAll().then((rows: any[]) => {
                console.log(' LocalData init ', this.tbName, rows)
                this.localData.init(rows)
                reslove(rows);
            })
        })

    }


    //事务处理
    transactionData(sqlStr: string, list: LocalDataType[]) {
        return Sqlite3Mgr.transactionData(this._dbName, sqlStr, list)
    }

    //插入给定数组的数据，已经存在会插入失败。
    insertAll(list: LocalDataType[]) {
        return new Promise((resolve, reject) => {
            let temp = this._tableParser.exchangeListToSql(list)
            if (!temp) {
                reject('insertAll temp is null ')
                return;
            }
            var sqlStr = this._tableParser.insertAllStr;
            if (sqlStr) {
                this.transactionData('INSERT INTO ' + this.tbName + ' ' + sqlStr, temp).then((err: string) => {
                    if (!err) {
                        resolve('')
                    } else {
                        engine.error(err)
                        reject(err)
                    }
                })
            } else {
                // LogUtils.error('insertAll  ', sqlStr)
                reject('insertAll sqlStr is null');
            }
        })

    }

    //更新给定数组的数据，不存在时更新无效
    updateAll(list: LocalDataType[]) {
        return new Promise((resolve, reject) => {
            let temp = this._tableParser.exchangeListToSql(list)
            if (!temp) {
                reject('updateAll temp is null ')
                return;
            }
            var sqlStr = this._tableParser.updateAllStr;
            if (sqlStr) {
                this.transactionData('update ' + this.tbName + ' ' + sqlStr, temp).then((err: string) => {
                    if (!err) {
                        resolve('')
                    } else {
                        engine.error(err)
                        reject(err)
                    }
                })
            } else {
                // LogUtils.error('updateAll  ', sqlStr)
                reject('updateAll sqlStr is null');
            }
        })

    }
    //删除给定数组的数据，不存在删除无效
    deleteAll(list: LocalDataType[]) {
        return new Promise((resolve, reject) => {
            let temp = this._tableParser.exchangeListToSql(list)
            if (!temp) {
                reject('deleteAll temp is null ')
                return;
            }
            var sqlStr = this._tableParser.deleteAllStr;
            if (sqlStr) {
                this.transactionData('delete from ' + this.tbName + ' ' + sqlStr, temp).then((err: string) => {
                    if (!err) {
                        resolve('')
                    } else {
                        engine.error(err)
                        reject(err)
                    }
                })
            } else {
                reject('deleteAll sqlStr is null');
            }
        })

    }

    //保存数据
    save(): Promise<any> {
        return new Promise((reslove: Function, reject: Function) => {
            let insertList: LocalDataType[] = this.localData.getInsertList();
            let updateList: LocalDataType[] = this.localData.getUpdateList();
            let deleteList: LocalDataType[] = this.localData.getDeleteList();
            if (insertList.length > 0 || updateList.length > 0 || deleteList.length > 0) {
                //如果表不存在，还需要先创建表
                this.isExist().then((flag: boolean) => {
                    if (!flag) {
                        this.create().then((err: string) => {
                            if (!err) {
                                this.saveList(insertList, updateList, deleteList).then(() => {
                                    reslove()
                                }, (error: string) => {
                                    reject(error)
                                })
                            } else {

                            }
                        })
                    } else {
                        this.saveList(insertList, updateList, deleteList).then(() => {
                            reslove()
                        }, (error: string) => {
                            reject(error)
                        })
                    }
                })
            } else {
                reslove()
            }
        })
    }

    comparison(db: LocalDataType[]) {
        this.localData.comparison(db)
    }

    saveTable(sList: any) {
        // let sList: server.RoleInfo[] = this.getServerInfos(list);
        this.comparison(sList);
        return this.save();
    }

    private saveList(insertList: LocalDataType[], updateList: LocalDataType[], deleteList: LocalDataType[]) {
        return new Promise((reslove: Function, reject: Function) => {
            let p = []
            if (insertList.length > 0) {
                let dp = this.insertAll(insertList)
                if (dp) {
                    p.push(dp)
                }
            }


            if (updateList.length > 0) {
                let dp = this.updateAll(updateList)
                if (dp) {
                    p.push(dp)
                }
            }


            if (deleteList.length > 0) {
                let dp = this.deleteAll(deleteList)
                if (dp) {
                    p.push(dp)
                }
            }
            if (p.length == 0) {
                reslove()
            } else {
                Promise.all(p).then(() => {
                    reslove()
                }, (error: string) => {
                    reject(error)
                })
            }

        })

    }
}